iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 19
0

ConfigMap

K8s透過ConfigMap將配置文件從容器中解耦, 讓用戶可以集中管理配置內容, 增加了容器的可移值性。
一個ConfigMap就是一組配置數據的集合,其結構是以Key-Value的格式儲存, 這些數據可透過掛Volume或是傳遞環境變數的方式注入到Pod裡面, 讓容器可以應用。

創建 ConfigMap

這邊使用配置YAML的方式創建, ConfigMap的spec配置字段有:apiVersion, kind, metadata, data, data是用於儲存數據的關鍵字:

apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap-demo
  namespace: default
data:
  test.info: hello
  test.type: demo
  test.file: /var/log/test.log
  • 查看結果
-> % kubectl get configmap -o yaml
apiVersion: v1
items:
- apiVersion: v1
  data:
    test.file: /var/log/test.log
    test.info: hello
    test.type: demo
  kind: ConfigMap
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"v1","data":{"test.file":"/var/log/test.log","test.info":"hello","test.  type":"demo"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"configmap-demo","namespace":"default"}}
    creationTimestamp: "2020-09-26T14:26:45Z"
    name: configmap-demo
    namespace: default
    resourceVersion: "637447"
    selfLink: /api/v1/namespaces/default/configmaps/configmap-demo
    uid: 54c0f06c-f9d3-4be8-8558-a780700f044d
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

向Pod 傳遞 ConfigMap內容

  • Pod spec 配置字段
valueFrom:
  configMapKeyRef:
    key:
    name:
      optional:
  • name: 要引用的ConfigMap名稱

  • key: 指定要引用的ConfigMap中的特定的key

  • optional: 標記讓Pod知道這個引用是否可正常使用

  • 使用環境變量 配置YAML ConfigMap+Pod , 兩個資源中間使用---相隔

  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: configmap-demo-2
    namespace: default
  data:
    httpd_port: "8080"
    verbose_level: "-vv"
  ---
  apiVersion: v1
  kind: Pod
  metadata:
    name: configmap-env-demo
    namespace: default
  spec:
    containers:
    - image: evelynocean/hello:v1.0.0
      name: hello
      command: ["./hello"]
      args: ["-p","$(HTTPD_PORT)"]
      env:
      - name: HTTPD_PORT
        valueFrom:
          configMapKeyRef:
            name: configmap-demo-2
            key: httpd_port
      - name: HTTPD_LOG_VERBOSE
        valueFrom:
          configMapKeyRef:
            name: configmap-demo-2
            key: verbose_level
            optional: true
  • 查看結果[COMMAND]是否有吃到ConfigMap參數
 -> % kubectl exec configmap-env-demo ps aux
 USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
 root         1  0.2  0.2  38316  5344 ?        Ssl  07:16   0:00 ./hello -p 8080
  • 使用 envFrom字段直接載入conMap資訊
spec:
  containers:
  - images: some-image
    envFrom:
    - prefix <string>
      configMapRef:
      name <string>
      optional <boolean>

envFrom適用於一次導入多個ConfigMap的情境, 為了避免ConfigMap彼此之間命名重複, 可以使用prefix加上前綴做分別。
如果原本的key使用了-, 則會被自動替換為_

  • 修改上一個配置改用envFrom的方式
apiVersion: v1
kind: Pod
metadata:
  name: configmap-envfrom-demo
  namespace: default
spec:
  containers:
  - image: evelynocean/hello:v1.0.0
    name: hello
    command: ["./hello"]
    args: ["-p","$(PRE_HTTPD_PORT)"]
    envFrom:
    - prefix: PRE_
      configMapRef:
        name: configmap-demo-2
        optional: false
  • 查看結果是否有吃到ConfigMap參數
  -> % kubectl exec configmap-envfrom-demo printenv
  PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  HOSTNAME=configmap-envfrom-demo
  PRE_verbose_level=-vv
  PRE_httpd_port=8080
  KUBERNETES_PORT=tcp://10.96.0.1:443
  KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
  KUBERNETES_PORT_443_TCP_PROTO=tcp
  KUBERNETES_PORT_443_TCP_PORT=443
  KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
  KUBERNETES_SERVICE_HOST=10.96.0.1
  KUBERNETES_SERVICE_PORT=443
  KUBERNETES_SERVICE_PORT_HTTPS=443
  GOLANG_VERSION=1.9.2
  GOPATH=/go
  HOME=/root
  • 使用 volumn掛載conMap資訊
  apiVersion: v1
  kind: Pod
  metadata:
    name: configmap-volume-demo
    namespace: default
  spec:
    containers:
    - image: nginx:v1.0.0
      name: nginx
      volumeMounts:
      - name: ngxconfig
        mountPath: /etc/nginx/conf.d/
        readOnly: true
    volumes:
    - name: ngxconfig
      configMap:
        name: nginx-config-files
  • Pod 和 ConfigMap需為同一個 namespace
  • 以環境參數載入ConfigMap時, 如果ConfigMap中的key不存在不會影響Pod的啟動, 只會在log留下紀錄。
  • 以volume掛載ConfigMap時要先於Pod之前啟動, 否則會導致Pod也無法正常啟動

Secret

Secret 類似ConfigMap, 主要用來存放敏感數據, 例如: 密碼, 憑證, 私鑰和 SSH Key等, 由於K8s上只要有權限的人都看得到Secret的內容, 所以並沒有真的很Secret。
Secret由四種類型組成:

  • Opaque: 自定義數據內容; 使用base64編碼, 識別符generic
  • kubernetes.io/service-account-token: Service Account認證訊息, 可在創建Service Account時由K8s自動創建
  • kubernetes.io/dockerconfigjson: 存放docker registry認證訊息, 識別符docker-registry
  • kubernetes.io/tls: 存放SSL通訊私鑰, 識別符tls

創建Secret

Secret spec配置字段除了apiVersion, kind, metadata, 其他可用字段有:

  • data <map[string]string>: "key:value" 格式, 通常需要為base64編碼的字符串, 要自己編碼
  • stringData <map[string]string>: 明文定義"key:value" 格式 ,不需base64編碼, 這個字段不會被API輸出
  • type : 提供內部編程識別類別的type

Secret 除了kind 要替換為Secret 以及 使用secretName之外, spec內容與ConfigMap大致相同。

  • volume掛載Secret YAML
  apiVersion: v1
  kind: Secret
  metadata:
    name: nginx-ssl
  stringData:
    tls1: crt
    tls2: key
  type: Opaque
  ---
  apiVersion: v1
  kind: Pod
  metadata:
    name: secret-volume-demo
  spec:
    containers:
    - image: nginx:latest
      name: nginx
      volumeMounts:
      - name: nginxcert
        mountPath: /etc/nginx/ssl
        readOnly: true
    volumes:
    - name: nginxcert
      secret:
        secretName: nginx-ssl
  • 查看結果
-> % kubectl exec secret-volume-demo ls /etc/nginx/ssl
tls1
tls2

imagePullSecret

K8s 可以透過imagePullSecret從需要認證的私倉取得image, 它透過Secret提供的密碼讓kubectl在拉image之前就能通過認證。
使用方式有兩種:

  1. 在定義Pod配置時使用imagePullSecret字段
  2. 添加創建的Secret到特定的ServiceAccount, 再透過ServiceAccount 使用imagePullSecret的資訊

實務上使用ServiceAccount去拉images會比在每個Pod配置檔案中添加imagePullSecret來得方便。

今日小結

讀到這裡我看了一下我們目前在使用的K8s部署專案, ConfigMap一個專案都會用1-2個, Secret 主要用來放置可以查看的私鑰, Secret真的沒有很Secret, 真的要放敏感資料的話還是要評估一下。


上一篇
day 18 Volume(2) - Persistent Volume
下一篇
day 20 StatefulSet Controller
系列文
K8S - 30天從擦槍到提槍上陣學習筆記。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言